﻿using System;
using System.Collections.Generic;
using System.ServiceModel.Web;
using System.Web.SessionState;
using Dogshow.Linq2SQLRepository;
using Dogshow.Model;
using Dogshow.Model.Validation;
using Dogshow.Web.Helpers;
using Dogshow.Web.Requests;
using DogshowRepository;
using FluentValidation;
using Ninject;
using Pas = Dogshow.Model.Pas;
using Titula = Dogshow.Model.Titula;
using System.Linq;
using Kinolog = Dogshow.Model.Kinolog;
using Dogshow.Model.Extensions;

namespace Dogshow.Web.Services
{
    public class RepoServices : IRepoServices
    {
        private static readonly KinoloskoDrustvoValidator s_KinoloskoDrustvoValidator = new KinoloskoDrustvoValidator();

        private static readonly MestoValidator s_MestaValidator = new MestoValidator();

        public IEnumerable<RasaPsa> VratiSveRasePasa()
        {
            var kernel = GetKernel();
            var raseRepos = kernel.Get<IRaseRepository>();
            return raseRepos.VratiSve().OrderBy(x => x.NazivRase);
        }

        public IEnumerable<Titula> VratiMoguceTitule()
        {
            var repos = GetKernel().Get<ITituleRepository>();
            return repos.VratiSve().OrderBy(x => x.Id);
        }

        public IEnumerable<Pas> VratiPse()
        {
            var repos = GetKernel().Get<IPsiRepository>();
            return repos.VratiSve();
        }

        public IEnumerable<InfoOPsu> VratiInfoOPsima()
        {
            //var rase = GetKernel().Get<IRaseRepository>().VratiSve();
            var repos = GetKernel().Get<IPsiRepository>();
            var info = repos.VratiInfoOPsima();
            //info = info.Union(rase.Select(x => new InfoOPsu() {FciGrupa = x.FciGrupa, Rasa = x.NazivRase + "(" + x.OriginalniNazivRase + ")"})).ToArray();
            return info;
        }

        public void SacuvajRasePasa(IEnumerable<RasaPsa> rase)
        {
            var validator = new RasaPsaValidator();
            var repos = GetKernel().Get<IRaseRepository>();
            foreach (var rasa in rase)
            {
                if (validator.Validate(rasa).IsValid)
                {
                    repos.Sacuvaj(rasa);
                }
            }
        }

        public IEnumerable<Kinolog> VratiKinologe()
        {
            var kernel = GetKernel();
            return kernel.Get<IKinoloziRepository>().VratiSve().OrderBy(x => x.ImeIPrezime);
        }

        public IEnumerable<Kinolog> VratiKinologePoStatusu(string status)
        {
            int st;
            if (Int32.TryParse(status, out st))
            {
                return GetKernel().Get<IKinoloziRepository>().VratiKinologeSaStatusom((VrstaKinologa) Enum.ToObject(typeof (VrstaKinologa), st));
            }
            return new Kinolog[0];
        }

        public void SacuvajKinologe(IEnumerable<Kinolog> kinolozi)
        {
            var repo = GetKernel().Get<IKinoloziRepository>();
            foreach (var kinolog in kinolozi)
            {
                repo.Sacuvaj(kinolog);
            }
        }

        public IEnumerable<FciGrupa> VratiSveFciGrupe()
        {
            return GetKernel().Get<IRaseRepository>().VratiFciGrupe();
        }

        public bool PostojiPas(string brojRodovnika, string idPsa)
        {
            brojRodovnika = brojRodovnika.Replace('|', '/');
            return GetKernel().Get<IPsiRepository>().PostojiPas(brojRodovnika, Int32.Parse(idPsa));
        }

        public Pas VratiPsaPoBrojuRodovnika(string brojRodovnika)
        {
            brojRodovnika = brojRodovnika.Replace('|', '/');
            return GetKernel().Get<IPsiRepository>().VratiPsaPoBrojuRodovnika(brojRodovnika);
        }

        public SnimiPsaResponse SacuvajPsa(Pas pas)
        {
            var repos = GetKernel().Get<IPsiRepository>();
            var postoji = repos.PostojiPas(pas.BrojRodovnika, pas.Id);
            if (postoji)
            {
                return new SnimiPsaResponse { Error = "Snimanje podataka o psu nije dozvoljeno: Dupliran broj rodovnika" };
            }
            var validator = new PasValidator();
            if (!validator.Validate(pas).IsValid)
            {
                return new SnimiPsaResponse { Error = "Snimanje podataka o psu nije dozvoljeno: Podaci nisu validni" };
            }
            
            repos.Sacuvaj(pas);
            return new SnimiPsaResponse();
        }

        public Pas VratiPsa(string id)
        {
            return GetKernel().Get<IPsiRepository>().VratiPoId(Int32.Parse(id));
        }

        public IEnumerable<Titula> VratiTitule()
        {
            return GetKernel().Get<ITituleRepository>().VratiSve();
        }

        public IEnumerable<Kinolog> VratiKinologaSaImenom(string deoImena)
        {
            var results = GetKernel().Get<IKinoloziRepository>().VratiKinologaSaImenom(deoImena);
            return results;
        }

        public IEnumerable<Pas> PretraziPse()
        {
            if (WebOperationContext.Current == null)
                throw new InvalidOperationException("WebOperationContext is null");

            var ime = QueryString.GetString("ime");
            int rasa = QueryString.GetInt("rasa", 0);
            int fci = QueryString.GetInt("fci", 0);
            int idVlasnika = QueryString.GetInt("vlasnik", 0);
            int idOdgajivaca = QueryString.GetInt("odgajivac", 0);
            
            return GetKernel().Get<IPsiRepository>().PretraziPse(ime, rasa, fci, idVlasnika, idOdgajivaca);
        }

        public void SacuvajKinoloskoDrustvo(KinoloskoDrustvo kinoloskoDrustvo)
        {
            if (!s_KinoloskoDrustvoValidator.Validate(kinoloskoDrustvo).IsValid)
            {
                throw new Exception("Podaci nisu validni");
            }
            
            kinoloskoDrustvo.FixForeignKeys();
            GetKernel().Get<IKinoloskaDrustvaRepository>().Sacuvaj(kinoloskoDrustvo);
        }

        public IEnumerable<KinoloskoDrustvo> VratiKinoloskaDrustva()
        {
            return GetKernel().Get<IKinoloskaDrustvaRepository>().VratiSve().OrderBy(x => x.Mesto.Naziv);
        }

        public IEnumerable<Mesto> VratiMesta1()
        {
            return GetKernel().Get<IMestaRepository>().VratiSve().OrderBy(x => x.Naziv);
        }

        public void SacuvajMesto(Mesto mesto)
        {
            if (!s_MestaValidator.Validate(mesto).IsValid)
            {
                throw new Exception("Podaci o mestu nisu validni");
            }
            GetKernel().Get<IMestaRepository>().Sacuvaj(mesto);
        }

        public KinoloskoDrustvo VratiKinoloskoDrustvoPoId(int id)
        {
            return GetKernel().Get<IKinoloskaDrustvaRepository>().VratiPoId(id);
        }

        public int SacuvajPodatkeOIzlozbi(Izlozba izlozba)
        {
            return GetKernel().Get<IIzlozbeRepository>().Sacuvaj(izlozba);
        }

        public IEnumerable<Titula> VratiTituleIzlozbe(int idIzlozbe)
        {
            return GetKernel().Get<IIzlozbeRepository>().VratiTituleIzlozbe(idIzlozbe);
        }

        public void SacuvajTituleIzlozbe(int id, int[] titule)
        {
            GetKernel().Get<IIzlozbeRepository>().SacuvajTitule(id, titule);
        }

        public Izlozba VratiIzlozbu(int id)
        {
            return GetKernel().Get<IIzlozbeRepository>().VratiPoId(id);
        }

        private static IKernel GetKernel()
        {
            var kernel = ((IKernel) Bootstrap.Bootstrapper.Container);
            return kernel;
        }
    }
}
